home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’95
/
CantTouchThis
/
CantTouchThis.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-24
|
9KB
|
424 lines
/*
CantTouchThis Show interesting effects
@MacHack bh noEsis Software Construction
*/
/*
Last Build:
22jun95
DOCS:
*/
//****************************************************************
// I N C L U D E S
#include <Types.h>
#include <Memory.h>
#include <SetUpA4.h>
#include <Quickdraw.h>
#include <QDOffscreen.h>
#include <LowMem.h>
#include <Errors.h>
#include <GestaltEqu.h>
#include <Resources.h>
#include <Events.h>
#include <Windows.h>
#include <Sound.h>
#include <AppleEvents.h>
#include <AEObjects.h>
#include <AERegistry.h>
#include <AEPackObject.h>
#include <Aliases.h>
#include <Processes.h>
#include <Sound.h>
#include <SANE.h>
#ifndef TRUE
#define FALSE 0
#define TRUE (!FALSE)
#endif
#define DEBUG
#ifdef DEBUG
pascal void NumToString(long,StringPtr);
#define ASSERT(x) { if (!(x)) { Str255 lineString; NumToString(__LINE__,lineString); DebugStr(lineString); }}
#else
#define ASSERT(x) ;
#endif
//****************************************************************
// C O N S T A N T S
// ShowInit
#define kOkMac 128
#define kNotOkMac 130
//****************************************************************
// G L O B A L S
struct NInitGlobals
{
Handle pH;
};
typedef struct NInitGlobals NInitGlobals;
NInitGlobals *gP;
static void *gOldJGNE;
Handle gSound;
SndChannelPtr gSndChP;
//****************************************************************
// F O R W A R D S
OSErr DoInstallPatch(void);
void DoAnimation( Rect trshR);
pascal void * SetJGNEFilter (void *newFilter);
Boolean myGNE (EventRecord *event, Boolean preResult);
void myJGNE (void);
extern OSErr
GetScriptableFinderTrashPos( Boolean usesystemmode, AESendMode sendmode, Boolean sendToSelf, Rect *r);
//****************************************************************
void main( void )
{
Handle tH;
OSErr err;
void *me; asm { MOVE.L A0,me }
//Debugger();
RememberA0 ( );
SetUpA4();
DetachResource (RecoverHandle (me));
tH = GetResource( 'PICT', 200);
if ( tH != 0) {
DetachResource( tH);
}
/*
gSound = GetResource('snd ',128);
if (gSound) {
DetachResource(gSound);
}
err = SndNewChannel( &gSndChP, sampledSynth, initMono, 0);
if (err != noErr) {
gSndChP = NULL;
}
*/
gSound = NULL;
gSndChP = NULL;
// ok, go to town
gOldJGNE = SetJGNEFilter (myJGNE);
gP = (NInitGlobals*) NewPtrSysClear( sizeof(NInitGlobals));
if ( !gP ) {
err = memFullErr;
goto DONE;
}
gP->pH = tH;
DONE:
/*
if ( err ) {
ShowIconFamily( kNotOkMac);
if ( gP )
DisposPtr( (Ptr)gP );
} else {
ShowIconFamily( kOkMac);
// resource is already marked 'locked', so no HLock() here...
}
*/
RestoreA4();
return;
}
//****************************************************************
#define JGNEFilter 0x29A
static pascal void * SetJGNEFilter (void *newFilter)
{
void *result = *(void **) JGNEFilter;
*(long *) JGNEFilter = (long) newFilter;
return (result);
}
//****************************************************************
static Boolean myGNE (EventRecord *event, Boolean preResult)
{
Rect tR;
Boolean postResult = preResult;
if (event->what == mouseDown) {
if ( *(long*)0x912 == 'inde' ) {
GetScriptableFinderTrashPos( TRUE, kAEWaitReply, TRUE, &tR);
if ( PtInRect( event->where, &tR) && *(long*)0x17E == 0) {
DoAnimation( tR);
event->what = nullEvent;
}
}
}
return (postResult);
}
//****************************************************************
static void myJGNE (void)
{
static Boolean inJGNE;
asm
{
MOVE.L A1,A0 ; save event record pointer from __GetA4
JSR __GetA4 ; point A1 at our A4
MOVE.L A4,-(A7) ; save old A4
MOVE.L (A1),A4 ; get new A4
MOVE.L A0,A1 ; restore old A1
TST.B inJGNE ; is myJGNE busy?
BNE @1 ; yes, so bail
MOVE.B #true,inJGNE ; mark myJGNE busy
MOVE.W D0,-(A7) ; push pre-result
MOVE.L A1,-(A7) ; push event record pointer
JSR myGNE ; do the real work
MOVE.L (A7)+,A1 ; restore event record pointer
ADDQ.L #2,A7 ; pop pre-result; post-result in D0
ASL.W #8,D0 ; bump C boolean to Lisa
MOVE.W D0,8(A7) ; stash result where caller expects it
MOVE.B #false,inJGNE ; mark myJGNE not busy
@1 MOVE.L gOldJGNE,A0 ; get previous jGNE
MOVE.L (A7)+,A4 ; restore A4
MOVE.L A0,-(A7) ; return to previous jGNE
}
}
//****************************************************************
void xDoAnimation(void);
void xDoAnimation()
{
GrafPtr savP;
CGrafPort dPort;
// Create a new GrafPort on top of the current port so as to
// disturb the graphics world as little as possible. This
// new GrafPort is the default through our copying operations.
GetPort( &savP);
OpenCPort( (CGrafPtr)&dPort);
SetPort( (GrafPtr)&dPort);
// Do something fun
;
SetPort( savP);
ClosePort( (GrafPtr)&dPort);
return;
}
//****************************************************************
#define MAX_INC 18
void DoAnimation( Rect trshR)
{
GrafPtr savP;
CGrafPort dPort;
Rect savScrnR, picR, offBufR, wR;
Rect tmpR, tmpR_0;
GWorldPtr savScrnGWPtr, picGWPtr, offBufGWPtr;
PixMapHandle pm;
GWorldPtr savGW;
GDHandle savGdH;
OSErr err;
short cnt, vInc, del, curAccl;
long t, startT;
THz savZone;
#ifdef APP
Handle pH;
#endif
//Debugger();
/*
if (gSound != NULL && gSndChP != NULL) {
SndPlay( gSndChP, gSound, true);
}
*/
savZone = GetZone();
SetZone( SystemZone());
// Save the 'Real' orignial port...
GetPort( &savP);
// Create a new GrafPort on top of the current port so as to
// disturb the graphics world as little as possible. This
// new GrafPort is the default through our copying operations.
OpenCPort( (CGrafPtr)&dPort);
SetPort( (GrafPtr)&dPort);
GetGWorld( &savGW, &savGdH);
#ifdef APP
//GetScriptableFinderTrashPos( false, kAEWaitReply, false, &trshR);
trshR.left = 400;
trshR.right = trshR.left + 32;
trshR.top = 640;
trshR.bottom = trshR.top + 32;
#endif
// Get the picture
#ifdef APP
pH = GetResource( 'PICT', 200); if ( pH == 0) goto DONE;
picR = (**(PicHandle)pH).picFrame;
#else
picR = (**(PicHandle)gP->pH).picFrame;
#endif
// calc drawing sizes
// TO DO: work on non-main screen correctly...
// savScr, tall column of saved screen
savScrnR.top = 0;
savScrnR.left = trshR.left;
savScrnR.right = savScrnR.left + (picR.right-picR.left);
savScrnR.bottom = trshR.bottom;
offBufR = picR;
offBufR.bottom += MAX_INC;
wR = savScrnR;
wR.top += 24;
wR.bottom = wR.top + picR.bottom - picR.top + MAX_INC;
ASSERT(savScrnR.left < savScrnR.right);
ASSERT(savScrnR.top < savScrnR.bottom);
// create offscreen worlds
err = NewGWorld( &savScrnGWPtr,0,&savScrnR,0,0,useTempMem); if ( err != noErr) goto DONE;
err = NewGWorld( &picGWPtr,0,&picR,0,0,useTempMem); if ( err != noErr) goto DONE;
err = NewGWorld( &offBufGWPtr,0,&offBufR,0,0,useTempMem); if ( err != noErr) goto DONE;
// init drawing
SetGWorld( picGWPtr, 0);
EraseRect( &picGWPtr->portRect);
#ifdef APP
DrawPicture( (PicHandle)pH, &picR);
#else
DrawPicture( (PicHandle)gP->pH, &picR);
#endif
SetGWorld( offBufGWPtr, 0);
LockPixels(GetGWorldPixMap(offBufGWPtr));
EraseRect( &offBufGWPtr->portRect);
// the savScrn rect is always 0,0 -> top,left
tmpR = savScrnR;
tmpR.right -= tmpR.left;
tmpR.left -= tmpR.left;
tmpR.bottom -= tmpR.top;
tmpR.top -= tmpR.top;
SetGWorld( savScrnGWPtr, 0);
EraseRect( &savScrnGWPtr->portRect);
LockPixels((pm=GetGWorldPixMap(savScrnGWPtr)));
CopyBits( (BitMap*)(&(((GrafPtr)&dPort)->portBits)),
(BitMap*)(*pm),
&savScrnR, &tmpR,
patCopy, 0);
#define BASE_INC 1
// Animation Loop
startT = TickCount();
for ( curAccl=1, del=1, cnt=0; cnt<savScrnGWPtr->portRect.bottom/6; cnt++) {
if ( cnt%5 == 0) curAccl++;
vInc = BASE_INC + curAccl;
wR.bottom += vInc;
wR.top += vInc;
// copy sav to off
SetGWorld( offBufGWPtr, 0);
tmpR = wR;
tmpR.right -= tmpR.left;
tmpR.left -= tmpR.left;
tmpR.bottom -= tmpR.top;
tmpR.top -= tmpR.top;
tmpR_0 = wR;
tmpR_0.right -= tmpR_0.left;
tmpR_0.left -= tmpR_0.left;
LockPixels((pm=GetGWorldPixMap(offBufGWPtr)));
CopyBits( (BitMap*)(*(savScrnGWPtr->portPixMap)),
(BitMap*)(*pm),
&tmpR_0, &tmpR,
patCopy, 0);
// copy pic to off, picR is already 0-based
tmpR = picR;
tmpR.top += MAX_INC;
tmpR.bottom += MAX_INC;
CopyBits( (BitMap*)(*(picGWPtr->portPixMap)),
(BitMap*)(*pm),
&picR, &tmpR,
patOr, 0);
// copy off to dPort
tmpR = wR;
tmpR.right -= tmpR.left;
tmpR.left -= tmpR.left;
tmpR.bottom -= tmpR.top;
tmpR.top -= tmpR.top;
SetGWorld( savGW, savGdH);
CopyBits( (BitMap*)(*(offBufGWPtr->portPixMap)),
(BitMap*)(&(((GrafPtr)&dPort)->portBits)),
&tmpR, &wR,
patCopy, 0);
if ( t != startT) {
Delay( del, &t);
}
}
// Clean up
DisposeGWorld( savScrnGWPtr);
DisposeGWorld( picGWPtr);
DisposeGWorld( offBufGWPtr);
DONE:
SetPort( savP);
ClosePort( (GrafPtr)&dPort);
SetZone( savZone);
return;
}
//***********************************************************************************
// E N D O F L I S T I N G